package com.topcent.tioxyc.consumer;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.rabbitmq.client.Channel;
import com.topcent.tioxyc.constants.KeyConstant;
import com.topcent.tioxyc.pojo.cc.PaymentTrackingjhdCC;
import com.topcent.tioxyc.pojo.cc.SkdNoCC;
import com.topcent.tioxyc.util.ApiClient;
import com.topcent.tioxyc.util.ConnmeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;


/**
 * @author: 陈百万
 * @date: 2025/11/13 14:28
 * @Description: 收款单数据创建关联数据到收款跟踪数据表单
 */
@Component
@RabbitListener(queues = "skdTracking")
@Slf4j
public class SkdTrackingConsumer {

    @Lazy
    @Autowired
    private ThreadPoolTaskExecutor businessExecutor;

    private static final String DATA_CREATE = "data_create";
    private static final String DATA_UPDATE = "data_update";

    @RabbitHandler
    public void handleMessage(String msg, Channel channel, Message message) throws IOException {
        try {
            // 异步操作
            businessExecutor.submit(() -> {
                try {
                    sdkOrder(msg); // 处理逻辑
                } catch (Exception e) {
                    log.error("异步处理简道云推送失败，payload:{}", msg, e);
                }
            });

            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            System.out.println("Message acknowledged");
        } catch (Exception e) {
            // 处理异常并拒绝消息
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
            System.err.println("发送消息失败，重试中 " + e.getMessage());
        }
    }

    // ========== 处理收款单赋值逻辑 ==========
    private void sdkOrder(String payload) {
        JSONObject payloadJSON = JSONUtil.parseObj(payload);
        String op = payloadJSON.getStr("op");
        String data = payloadJSON.getStr("data");
        if (DATA_CREATE.equals(op)) {
            changeSkdOrder(data);
        }
    }

    // 方法
    private void changeSkdOrder(String data) {
        Header[] headers = ConnmeUtils.createHeaders();
        SkdNoCC skdNoCC = JSONUtil.toBean(data, SkdNoCC.class);
        log.info("开始处理收款单数据，收款单号：{}", skdNoCC.get_widget_1721705341229());

        try {
            // 1. 处理SkdNoCC：提取预收款/尾款，合并同销售单号金额
            Map<String, BigDecimal> salesAmountMap = mergeSalesAmount(skdNoCC);
            if (salesAmountMap.isEmpty()) {
                log.info("收款单{}无有效预收款/尾款数据，跳过", skdNoCC.get_widget_1721705341229());
                return;
            }

            // 2. 加载收款跟踪数据，构建销售单号→实体索引（提升匹配效率）
            List<PaymentTrackingjhdCC> paymentList = getPaymentTrackingListFromApi();
            Map<String, PaymentTrackingjhdCC> paymentIndex = buildPaymentIndexBySalesNo(paymentList);
            log.info("加载收款跟踪数据{}条，构建索引完成", paymentList.size());

            // 3. 匹配并更新指定字段（仅已回款金额+回款时间/月份）
            int successCount = 0;
            for (Map.Entry<String, BigDecimal> entry : salesAmountMap.entrySet()) {
                String salesNo = entry.getKey();
                BigDecimal totalAmount = entry.getValue();
                PaymentTrackingjhdCC payment = paymentIndex.get(salesNo);

                if (payment == null) {
                    log.warn("销售单号{}未找到对应收款跟踪数据，跳过", salesNo);
                    continue;
                }

                // 4. 仅更新3个指定字段（严格按需求）
                payment.set_widget_1759203125370(totalAmount); // 已回款金额（合并后的预收款/尾款）
                payment.set_widget_1759203125376(skdNoCC.get_widget_1724133481201()); // 实际回款时间（过账日期）
                // 计算回款月份（UTC时间，月初0点）
                payment.set_widget_1759203125377(calculatePaymentMonth(skdNoCC.get_widget_1724133481201()));

                // 5. 更新到简道云
                updatePaymentTrackingToJdy(headers, "669cb709a73cc1289c49800e", "68db4c7420407efb3e3bc238", payment);
                successCount++;
                log.debug("更新销售单号{}收款跟踪数据成功，已回款金额：{}", salesNo, totalAmount);
            }

            log.info("收款单{}处理完成，成功更新{}条收款跟踪数据", skdNoCC.get_widget_1721705341229(), successCount);
        } catch (Exception e) {
            log.error("处理收款单数据失败", e);
        }
    }

    /**
     * 提取预收款/尾款，合并同销售单号的金额（预收款和尾款二选一）
     */
    private Map<String, BigDecimal> mergeSalesAmount(SkdNoCC skdNoCC) {
        Map<String, BigDecimal> amountMap = new HashMap<>();

        // 优先处理预收款（如果有数据）
        if (skdNoCC.get_widget_1721546510495() != null && !skdNoCC.get_widget_1721546510495().isEmpty()) {
            for (SkdNoCC.ysk ysk : skdNoCC.get_widget_1721546510495()) {
                String salesNo = ysk.get_widget_1721546510504();
                BigDecimal amount = ysk.get_widget_1721546510520() != null ? ysk.get_widget_1721546510520() : BigDecimal.ZERO;
                if (salesNo != null && !salesNo.trim().isEmpty() && amount.compareTo(BigDecimal.ZERO) > 0) {
                    // 合并金额：相同销售单号累加
                    amountMap.merge(salesNo.trim(), amount, BigDecimal::add);
                }
            }
        }
        // 预收款无数据时，处理尾款
        else if (skdNoCC.get_widget_1721548605263() != null && !skdNoCC.get_widget_1721548605263().isEmpty()) {
            for (SkdNoCC.wk wk : skdNoCC.get_widget_1721548605263()) {
                String salesNo = wk.get_widget_1721548605264();
                BigDecimal amount = wk.get_widget_1721548605266() != null ? wk.get_widget_1721548605266() : BigDecimal.ZERO;
                if (salesNo != null && !salesNo.trim().isEmpty() && amount.compareTo(BigDecimal.ZERO) > 0) {
                    amountMap.merge(salesNo.trim(), amount, BigDecimal::add);
                }
            }
        }

        return amountMap;
    }

    /**
     * 构建销售单号→收款跟踪实体的索引（复用唯一码提取逻辑）
     */
    private Map<String, PaymentTrackingjhdCC> buildPaymentIndexBySalesNo(List<PaymentTrackingjhdCC> paymentList) {
        Map<String, PaymentTrackingjhdCC> index = new HashMap<>();
        for (PaymentTrackingjhdCC payment : paymentList) {
            String uniqueCode = payment.get_widget_1760327721440();
            if (uniqueCode == null || uniqueCode.trim().isEmpty()) {
                continue;
            }
            // 从唯一码提取销售单号（复用已有逻辑，兼容两种格式）
            String salesNo = extractSalesNoFromUniqueCode(uniqueCode);
            if (salesNo != null && !salesNo.trim().isEmpty()) {
                // 若同一销售单号对应多个收款跟踪数据，取第一个（可根据业务调整）
                index.putIfAbsent(salesNo, payment);
            }
        }
        return index;
    }

    /**
     * 计算回款月份（UTC时间，月初0点，与原有逻辑一致）
     */
    private Date calculatePaymentMonth(Date paymentDate) {
        if (paymentDate == null) {
            return null;
        }
        Calendar utcCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
        utcCalendar.setTime(paymentDate);
        utcCalendar.set(Calendar.DAY_OF_MONTH, 1);
        utcCalendar.set(Calendar.HOUR_OF_DAY, 0);
        utcCalendar.set(Calendar.MINUTE, 0);
        utcCalendar.set(Calendar.SECOND, 0);
        utcCalendar.set(Calendar.MILLISECOND, 0);
        return utcCalendar.getTime();
    }

// 复用已有工具方法（无需修改）
    /** 从唯一码提取销售单号 */
    private String extractSalesNoFromUniqueCode(String uniqueCode) {
        String trimmed = uniqueCode.trim();
        String[] parts = trimmed.split("-");
        return parts.length > 0 ? parts[parts.length - 1].trim() : null;
    }

    /** 简道云更新收款跟踪数据 */
    private void updatePaymentTrackingToJdy(Header[] headers, String appId, String entryId, PaymentTrackingjhdCC payment) {
        String dataId = payment.get_id();
        if (dataId == null) throw new IllegalArgumentException("收款跟踪数据data_id为空");

        Map<String, Object> params = new HashMap<>();
        params.put("app_id", appId);
        params.put("entry_id", entryId);
        params.put("is_start_trigger", "true");
        params.put("data_id", dataId);

        // 临时移除_id，避免序列化报错
        String tempId = payment.get_id();
        payment.set_id(null);
        params.put("data", ConnmeUtils.convertEntityToMapNull(payment));
        ApiClient.sendPostRequest(KeyConstant.Jian_URL + "/v5/app/entry/data/update", headers, JSONUtil.toJsonStr(params));
        payment.set_id(tempId);
    }


    /**
     * 加载收款跟踪数据（仅改名，逻辑不变）
     */
    private List<PaymentTrackingjhdCC> getPaymentTrackingListFromApi() {
        log.info("加载收款跟踪表单数据");
        List<PaymentTrackingjhdCC> paymentList = new ArrayList<>();
        Header[] headers = ConnmeUtils.createHeaders();
        Map<String, Object> parameter = new HashMap<>();
        parameter.put("app_id", "669cb709a73cc1289c49800e");
        parameter.put("entry_id", "68db4c7420407efb3e3bc238");
        boolean hasNext = true;
        String lastDataId = "";

        do {
            if (!lastDataId.isEmpty()) parameter.put("data_id", lastDataId);
            parameter.put("limit", 100);
            JSONObject response = ApiClient.sendPostRequest(KeyConstant.Jian_URL + "/v5/app/entry/data/list", headers, JSONUtil.toJsonStr(parameter));
            JSONArray dataArray = JSONUtil.parseArray(response.getStr("data"));
            List<PaymentTrackingjhdCC> batchList = JSONUtil.toList(dataArray, PaymentTrackingjhdCC.class);

            if (batchList.isEmpty()) {
                hasNext = false;
                continue;
            }

            paymentList.addAll(batchList);
            lastDataId = batchList.size() == 100 ? batchList.getLast().get_id() : "";
            hasNext = !lastDataId.isEmpty();
        } while (hasNext);

        return paymentList;
    }


}
